from django.db import models
from assets.models import environment_choice


class ProjectProduct(models.Model):
    product_name = models.CharField(unique=True, max_length=64, verbose_name='产品名称')
    product_memo = models.TextField(blank=True, verbose_name='产品描述', default='')
    product_department = models.CharField(max_length=16, blank=True, verbose_name='主管部门', default='')
    product_level = models.CharField(max_length=8, blank=True, verbose_name='安全等级', default='')
    product_create_time = models.DateTimeField(auto_now_add=True, verbose_name='创建时间')
    product_update_time = models.DateTimeField(auto_now_add=True)

    def __unicode__(self):
        return str(self.product_name)

    class Meta:
        db_table = 'ops_project_product'
        verbose_name = '产品配置表'
        verbose_name_plural = '产品配置表'


class AppDepartment(models.Model):
    name = models.CharField(max_length=32, null=True, blank=True, verbose_name=u"提出部门")
    code = models.CharField(max_length=14, null=True, blank=True, verbose_name=u'组织代码')

    def __unicode__(self):
        return str(self.name)

    class Meta:
        db_table = 'ops_appdepartment'
        verbose_name = u"上线单部门管理"
        verbose_name_plural = verbose_name


class AppInventory(models.Model):
    confirmation_choice=(
         ('0', u'无代码'),
         ('1', u'版本未上'),
         ('2', u'版本已上'),
    )
    process_choice=(
         ('0', u'未完成'),
         ('1', u'已完成'),
         ('2', u'无需测试'),
    )
    deploy_choice=(
         ('0', u'未部署'),
         ('1', u'已部署'),
         ('2', u'无需部署'),
    )
    delay_choice=(
         ('0', u'正常'),
         ('1', u'待定'),
    )
    display_choice=(
         ('0', u'否'),
         ('1', u'是'),
    )
    urgent_choice=(
         ('0', u'正常'),
         ('1', u'紧急'),
         ('2', u'灵活'),
    )

    project_models = (
        ('svn', 'svn'),
        ('git', 'git')
    )
    repo_models = (
        ('branch', 'branch'),
        ('tag', 'tag'),
        ('trunk', 'trunk'),
    )
    trade_method_choice = (
         ('0', u'无需验证'),
         ('1', u'当晚验证'),
         ('2', u'次日验证'),
         ('3', u'首笔验证'),
         ('4', u'跟随主体'),
    )

    repo = models.CharField(choices=project_models, max_length=3, verbose_name='仓库类型', default='svn')
    repo_url = models.CharField(max_length=100, default='', blank=True, verbose_name='项目仓库路径')
    repo_model = models.CharField(max_length=10, choices=repo_models, verbose_name='版本控制类型', default='tag')
    src_dir = models.CharField(max_length=100, default='', blank=True, verbose_name='代码检出目录')

    department = models.ForeignKey(AppDepartment, related_name='department_id', on_delete=models.PROTECT, verbose_name=u"提交部门")
    confirmation = models.CharField(max_length=1, default='1', choices=confirmation_choice, verbose_name=u"版本情况")
    system = models.ForeignKey(ProjectProduct, related_name='system_id', on_delete=models.PROTECT, verbose_name=u"对应产品")
    version = models.CharField(max_length=32, default='', blank=True, verbose_name=u"变更单版本编号")
    name = models.CharField(max_length=255, verbose_name=u"上线单名称")
    product_date = models.DateField(null=True, blank=True, verbose_name=u'上线时间')
    content = models.TextField(default='', blank=True, verbose_name=u"内容")
    product_no = models.CharField(max_length=32, default='', blank=True, verbose_name=u"运维变更单号")
    submitter = models.CharField(max_length=12, default='', blank=True, verbose_name=u"上线单提交人")
    checker = models.CharField(max_length=12, default='', blank=True, verbose_name=u"复核人")
    trade = models.TextField(default='', blank=True, verbose_name=u"涉及交易")
    tester = models.CharField(max_length=12, default='', blank=True, verbose_name=u"测试人员")
    process = models.CharField(max_length=1, default='0', choices=process_choice, verbose_name=u"测试进度")
    deploy = models.CharField(max_length=1, default='0', choices=deploy_choice, verbose_name=u"部署情况")
    description = models.CharField(max_length=128, default='', blank=True, verbose_name=u"备注")
    path = models.FileField(upload_to='inventory/%Y%m%d%H%M%S/', default='', blank=True, verbose_name=u"附件路径")
    urgent = models.CharField(max_length=1, default='0', choices=deploy_choice, verbose_name=u"提单状态")
    delay = models.CharField(max_length=1, default='0', choices=delay_choice, verbose_name=u"投产是否待定")
    create_time = models.DateTimeField(auto_now_add=True, verbose_name=u'创建时间')
    display = models.CharField(max_length=1, default='0', choices=display_choice, verbose_name=u"是否删除")
    trade_method = models.CharField(max_length=1, default='0', choices=trade_method_choice, verbose_name=u"验证方式")
    trade_content = models.TextField(default='', blank=True, verbose_name=u"验证交易")

    def __unicode__(self):
        return str(self.name)

    class Meta:
        db_table = 'ops_appinventory'
        permissions = (
            ("admin_appinventory", "测试管理权限"),
            ("test_appinventory", "外协测试权限"),
        )
        verbose_name = u"上线跟踪单管理"
        verbose_name_plural = verbose_name


class AppChange(models.Model):
    display_choice=(
         ('0', u'否'),
         ('1', u'是'),
    )

    name_id = models.ForeignKey(AppInventory, related_name='name_id', on_delete=models.CASCADE)
    reason = models.TextField(default=u'测试缺陷', verbose_name=u"变更原因")
    create_time = models.DateTimeField(auto_now_add=True, verbose_name=u'变更时间')
    display = models.CharField(max_length=1, default='0', choices=display_choice, verbose_name=u"是否删除")

    def __unicode__(self):
        return '%d-%s'%(self.id, str(self.name_id))

    class Meta:
        db_table = 'ops_appchange'
        verbose_name = u"二次变更管理"
        verbose_name_plural = verbose_name


class Project(models.Model):
    """项目表"""
    project_envs = environment_choice
    project_name = models.CharField(max_length=64, verbose_name='项目名称')
    project_env = models.SmallIntegerField(choices=project_envs, verbose_name='项目环境', default=1)
    # project_web = models.CharField(max_length=64, blank=True, verbose_name='项目网址', default='')
    project_product = models.ForeignKey('ProjectProduct', related_name='project_product', verbose_name='产品名称',
                                      on_delete=models.SET_NULL, blank=True, null=True)
    project_admin = models.ForeignKey('users.UserProfile', related_name='proj_admin', verbose_name='项目负责人',
                                      on_delete=models.PROTECT)
    project_member = models.ManyToManyField('users.UserProfile', related_name='proj_member', blank=True,
                                            verbose_name='项目成员')
    project_org = models.TextField(blank=True, default='', verbose_name='项目架构JSON数据')
    project_memo = models.TextField(blank=True, verbose_name='项目描述', default='')

    class Meta:
        db_table = 'ops_project'
        permissions = (
            ("view_project", "读取项目列表权限"),
            ("deploy_project", "代码发布权限"),
        )
        verbose_name = '项目列表'
        verbose_name_plural = '项目列表'
        unique_together = ("project_env", "project_name")


class ProjectConfig(models.Model):
    project_models = (
        ('svn', 'svn'),
        ('git', 'git')
    )
    repo_models = (
        ('branch', 'branch'),
        ('tag', 'tag'),
        ('trunk', 'trunk'),
    )
    project = models.OneToOneField('Project', on_delete=models.CASCADE)
    repo = models.CharField(choices=project_models, max_length=3, verbose_name='仓库类型')
    repo_user = models.CharField(max_length=10, verbose_name='仓库用户名', blank=True, default='')
    repo_password = models.CharField(max_length=16, verbose_name='仓库密码', blank=True, default='')
    repo_url = models.CharField(max_length=100, unique=True, verbose_name='项目仓库路径')
    repo_model = models.CharField(max_length=10, choices=repo_models, verbose_name='版本控制类型', default='branch')
    src_dir = models.CharField(max_length=100, verbose_name='代码检出目录')
    exclude = models.TextField(blank=True, verbose_name='排除文件', default='')
    run_user = models.CharField(max_length=10, verbose_name='运行服务用户', default='root')
    deploy_server = models.ManyToManyField('fort.FortServerUser', verbose_name='目标部署机器')
    deploy_webroot = models.CharField(max_length=100, verbose_name='目标机器webroot')
    deploy_releases = models.CharField(max_length=100, verbose_name='目标机器版本库地址')
    releases_num = models.PositiveSmallIntegerField(verbose_name='版本保留个数', default=20)
    prev_deploy = models.TextField(blank=True, verbose_name='代码检出前操作', default='')
    post_deploy = models.TextField(blank=True, verbose_name='代码检出后操作', default='')
    prev_release = models.TextField(blank=True, verbose_name='切换版本前操作', default='')
    post_release = models.TextField(blank=True, verbose_name='切换版本后操作', default='')
    versions = models.TextField(blank=True, verbose_name='存储部署过的版本', default='')
    wx_notice = models.BooleanField(blank=True, verbose_name='是否开启微信通知', default=False)
    to_mail = models.TextField(blank=True, default='', verbose_name='收件人邮箱')
    cc_mail = models.TextField(blank=True, default='', verbose_name='抄送人邮箱')

    class Meta:
        db_table = 'ops_project_config'
        verbose_name = '项目配置表'
        verbose_name_plural = '项目配置表'


class DeployLog(models.Model):
    """部署记录表"""
    d_types = (
        ('deploy', '部署'),
        ('rollback', '回滚')
    )
    project_config = models.ForeignKey('ProjectConfig', on_delete=models.CASCADE)
    deploy_user = models.ForeignKey('users.UserProfile', on_delete=models.CASCADE)
    d_type = models.CharField(max_length=10, choices=d_types, verbose_name='操作类型', default=0)
    branch_tag = models.CharField(max_length=16, verbose_name='分支或标签名称', default='master')
    release_name = models.CharField(max_length=100, verbose_name='部署版本')
    release_desc = models.CharField(max_length=100, verbose_name='版本说明')
    result = models.TextField(verbose_name='部署过程')
    c_time = models.DateTimeField(auto_now_add=True, verbose_name='操作时间')

    class Meta:
        db_table = 'ops_deploy_log'
        verbose_name = '部署记录表'
        verbose_name_plural = '部署记录表'


class Service(models.Model):
    """服务类型表"""
    project = models.ForeignKey('Project', on_delete=models.CASCADE)
    service_name = models.CharField(max_length=32, verbose_name='服务名称', help_text='数据库、中间件等')
    service_asset = models.ForeignKey('assets.Assets', verbose_name='提供服务的机器', on_delete=models.CASCADE)
    service_memo = models.TextField(blank=True, verbose_name='服务描述', default='')

    class Meta:
        db_table = 'ops_service'
        verbose_name = '服务类型表'
        verbose_name_plural = '服务类型表'
        unique_together = ("project", "service_name")
